package com.SpringMVC.simulation;

import com.SpringMVC.handlerInteceptor.TestHandlerInteceptor;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.support.ApplicationObjectSupport;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.HandlerExecutionChain;
import org.springframework.web.servlet.HandlerMapping;

import javax.servlet.http.HttpServletRequest;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.LinkedHashMap;

/**
 * Created by 41579 on 2017/5/22.
 */
public class SimulationRequestHandlerMapping extends ApplicationObjectSupport implements HandlerMapping,InitializingBean {
    private LinkedHashMap<String,SimulationHandlerMethod> handlerMethods = new LinkedHashMap<String, SimulationHandlerMethod>();
    private LinkedHashMap<String,Object> handlerMap = new LinkedHashMap<String, Object>();
    @Override
    public HandlerExecutionChain getHandler(HttpServletRequest httpServletRequest) throws Exception {
        Object obj = handlerMap.get("/"+httpServletRequest.getServletPath().split("/")[1]);
        HandlerExecutionChain chain = new HandlerExecutionChain(obj);
        chain.addInterceptor(new TestHandlerInteceptor());
        return chain;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
           String[] beanNames =  this.getApplicationContext().getBeanNamesForType(Object.class);
           for(String beanName:beanNames){
              Object obj$ = this.getApplicationContext().getBean(beanName);
              if(obj$.getClass().getAnnotation(Controller.class)!=null){
                  String conVal = obj$.getClass().getAnnotation(RequestMapping.class).value()[0];
                  Method[] methods = obj$.getClass().getMethods();
                  for(Method method$:methods) {
                      Annotation annotation = method$.getAnnotation(RequestMapping.class);
                      String value = "";
                      if(annotation!=null){
                          if(method$.getAnnotation(RequestMapping.class).value()!=null){
                              String[] values = method$.getAnnotation(RequestMapping.class).value();
                              SimulationHandlerMethod handlerMethod = new SimulationHandlerMethod(method$);
                              for(String value$:values){
                                  handlerMethods.put(conVal+"/"+value$,handlerMethod);
                              }
                          }else{
                              value = method$.getName();
                          }
                      }
                      SimulationHandlerMethod handlerMethod = new SimulationHandlerMethod(method$);
                      handlerMethods.put(conVal+"/"+value,handlerMethod);
                  }
              }
           }
    }

    public LinkedHashMap<String, SimulationHandlerMethod> getHandlerMethods() {
        return handlerMethods;
    }

    public void initApplicationContext() throws BeansException {
        String[] beanNames =  this.getApplicationContext().getBeanNamesForType(Object.class);
        for(String beanName:beanNames){
            Object obj$ = this.getApplicationContext().getBean(beanName);
            if(obj$.getClass().getAnnotation(RequestMapping.class)!=null){
                String conVal = obj$.getClass().getAnnotation(RequestMapping.class).value()[0];
                handlerMap.put(conVal,obj$);
            }
        }
    }

}
